class Vue{
  constructor(options)
  {
    // 1. 通过属性保存选项的数据(vm对象成员)
    this.$options = options || {}
    this.$data = options.data || {}
    this.$el = typeof options.el === 'string' 
      ? document.querySelector(options.el)
      : options.el

     // 2. 把data中的成员注入到vue实例中
     // (其实就是个代理，我们可以通过vm实例直接访问数据vm.xxx，而不是vm.data.xxx)
     this._proxyData(this.$data)
    
     // 3. 调用observer对象，把data中的属性转化为getter和setter，监听数据的变化
     new Observer(this.$data)

     // 4. 调用Compiler对象，解析指令和插值表达式。操作dom
    new Compiler(this)
  }

  _proxyData(data){
    Object.keys(data).forEach(key=>{
       Object.defineProperty(this,key,{
         enumerable:true,
         configurable:true,
         get(){
           return data[key] // 这里会触发observer的数据劫持的get
         },
         set(newVal){
           if(newVal === data[key]) return
           data[key] = newVal
         }
       })
    })
  }
}

